/*###############   COPYLEFT GPLv3 LICENSE   ###############
##
## JFX Version 0.2.7
## Website Management Software
## www.jfxcms.com
##
## Copyright 2009 GPLv3 - http://www.opensource.org/licenses/gpl-3.0.html
##
## Anthony Gallon
## oi_antz@hotmail.com
##
## Permission is hereby granted to any person having a copy of this software
## to freely use and modify as required so long as the copyright notices
## and branding remain intact.
##
## Full license details available at http://www.jfxcms.com/license
##
###############   COPYLEFT GPLv3 LICENSE   ###############*/


document.captureEvents = false;

JFX_AdminBlocks = function(options){
    var me = this;
    this.registerEventListener('doRebuildPage_exit', function(){me.drawToolbar();});
    this.fullScreen = false;
    this.numBlocks = Array();
    this.menuMapper = Array();
    this.urlMapper = Array();
    this.blockMapper = Array();
    this.elementForInserting = '';
    this.menuHoverId = '';
    this.page = new Object;
    this.mode = options.mode;
    this.ajaxUrl = AjaxUrl;
    this.pageid = options.pageid;
    this.templateid = options.templateid;
    this.workspaceid = options.workspaceid;
    this.page.id = 'jfxpage-'+options.pageid;
    this.page.pageid = options.pageid;
    this.page.details = options.pageDetails;
    this.rebuildPage();
    this.templatePageId = options.templatePageId;
    this.menuMapper = Array();
    this.urlMapper = Array();
    this.initMenu();
}

/**
 * JFX_AdminBlocks extends JFX_Base
 */
JFX_AdminBlocks.prototype = new JFX_Base();


JFX_AdminBlocks.prototype.drawToolbar = function(){
    this.tabber = new JFX_AdminTabber(this);
    this.tabber.hide();
    var val = $('#jfx-toolbar-buttons .jfx-block-buttons img').get(0);
    if(val) $(val).triggerEvent('click');
    if(this.page.elements.length > 0){
        this.tabber.focusTab(this.page.elements[0].details.id);
    }
}



/**
 * Initialize the menu system - display the toolbar
 * begin TODO: remove the url/menu mappers, replace with page load call to display menu
 */
JFX_AdminBlocks.prototype.initMenu = function(){
    $('#jfx-pages').click(function(){
        AdminBlocks.pages = this;
        $('#jfx-pages-menu').show('slow');
    }, function(){})

    this.menuMapper['jfx-toolbar'] = $('#jfx-toolbar').get(0);
    this.menuMapper['jfx-pages'] = $('#jfx-pages-menu').get(0);

    this.urlMapper['jfx-toolbar'] = 'toolbar/';
    this.urlMapper['jfx-pages'] = 'pages-menu/';

    $('#jfx-block-order').click(function(){
        var href = AjaxUrl+'/block-execution-order/?page='+AdminBlocks.pageid+'&KeepThis=true&TB_iframe=true&height=500&width=700';
        tb_show('Editing Block Execution Order', href, false);
    });
}
JFX_AdminBlocks.prototype.getMenuContent = function(itemId){
    if(typeof(this.urlMapper[itemId])!=='string') return;
    this.menuHoverId = itemId;
    $.get(this.ajaxUrl+'/'+this.urlMapper[itemId]+'?page='+AdminBlocks.pageid, this.showMenuContent);
}

JFX_AdminBlocks.prototype.showMenuContent = function(text){
    AdminBlocks.parseContent(AdminBlocks.menuHoverId, text);
}

JFX_AdminBlocks.prototype.parseContent = function(menuId, text){
    var menuContent = this.menuMapper[menuId];
    switch(menuId){
        case 'jfx-toolbar':

            $('#jfx-toolbar').draggable();
            $('#jfx-toolbar').resizable();
            JFXToolbarHide();

        break;
        case 'jfx-pages':
                    // first example
            AdminBlocks.menuMapper[AdminBlocks.menuHoverId].innerHTML = text;
            $("#jfx-page-tree").treeview({
                persist: "location",
                collapsed: true,
                unique: true
            });
            $('#jfx-pages-menu-inner a.edit-page').unbind('click');
            $('#jfx-pages-menu-inner a.edit-page').click(function(){
                var href = AjaxUrl+'/edit-page/?page='+AdminBlocks.pageid+'&KeepThis=true&TB_iframe=true&height=500&width=700';
                tb_show('Editing Page Details', href, false);
            });

        break;
    }
}
JFX_AdminBlocks.prototype.getBlockDetails = function(blockId){
    $.getJSON(this.ajaxUrl+'/get-block-details/', {blockId : blockId, pageid : AdminBlocks.page.id}, this.storeBlockDetails);
}

JFX_AdminBlocks.prototype.storeBlockDetails = function(json){
    AdminBlocks.setValue('blockMapper_'+json.id, json);
}
/**
 * end TODO: remove the url/menu mappers, replace with page load call to display menu
 */






/**
 * Fetch the JSON data for all page elements, then invoke the method to draw the dom
 */
JFX_AdminBlocks.prototype.rebuildPage = function(){
    this.log('rebuildPage :'+this.mode);
    this.page.elements = Array();
    this.page.deletedBlocks = Array();
    switch(this.mode){
        case 'template' :
            $.getJSON(this.ajaxUrl+'/get-template-elements/', {template : this.templateid}, this.doRebuildPage);
        break;
        case 'page' :
            $.getJSON(this.ajaxUrl+'/get-page-elements/', {page : this.pageid}, this.doRebuildPage);
        break;
    }

}
/**
 * Invoked by rebuildPage, obtains page data as json from prior ajax request, draws dom elements
 */
JFX_AdminBlocks.prototype.doRebuildPage = function(page){
    // build each page element
    for(var i=0; i<page.elements.length; i++){
        AdminBlocks.addElementToPage(page.elements[i], AdminBlocks.page.id); // creates actions too
    }

    // display arrows for moving up and down on all page elements
    AdminBlocks.showArrows();

    // create block actions for the page element, for renaming etc
    var pageEl = $('#'+AdminBlocks.page.id).get(0);
    AdminBlocks.createBlockActions(pageEl, AdminBlocks.page.details);

    AdminBlocks.trigg('doRebuildPage_exit');

}


/**
 * Delete a block from the page
 */
JFX_AdminBlocks.prototype.deleteBlock = function(id){
    id = id.split('-');
    id.splice(0, 1);
    id = id.join('-');
    var el = this.findElement(this.page.elements, id);
    if(el.elements.length > 0){
        if(confirm('This block has '+el.elements.length+' child blocks, are you sure you want to delete it?')){
            var node = $('#'+el.id).get(0);
            var parentEl = this.findParent(this.page, el.id);
            var k = this.findKey(parentEl, el.id);
            parentEl.elements.splice(k, 1);
            this.regenerateKeys(parentEl);
            node.parentNode.removeChild(node);
        }
    }else{
        var node = $('#'+el.id).get(0);
        var parentEl = this.findParent(this.page, el.id);
        var k = this.findKey(parentEl, el.id);
        parentEl.elements.splice(k, 1);
        this.regenerateKeys(parentEl);
        node.parentNode.removeChild(node);
    }
    this.page.deletedBlocks[this.page.deletedBlocks.length] = id;
    this.autoSavePage();
    if($('.jfx-block', this.page.id).get().length == 0){
        $('#jfx-actions-wrapper').css('display', 'none');
    }
}




/**
 *  Called for displaying pre-created (saved) blocks, not for inserting new blocks.
 */
JFX_AdminBlocks.prototype.addElementToPage = function(el, parentId, regenerateId){
    var gen, parentElement, i, element, contentArea, newEl, newid, blockDetails;

    // logging
    regenerateId = false;
    gen = (regenerateId) ? 'yes' : 'no';
    AdminBlocks.log('AdminBlocks.addElementToPage - element: '+el.details.id+', parent id: '+parentId+', regenerate id: '+gen);

    // make sure each instance of this module block has a unique id
    blockDetails = cloneObject(el.details);
    if(typeof(this.numBlocks[blockDetails.module_key])==='undefined') this.numBlocks[blockDetails.module_key] = 0;
    else this.numBlocks[blockDetails.module_key]++;

    // find our parent element details, lets see if it is the page itself (root block)
    if(el.id === this.page.id){
        // yep, the page is the new parent block
        parentElement = this.page;
        blockDetails.page_parent = 1;
    }else if(AdminBlocks.mode == 'template'){
        parentElement = this.findElement(this.page.elements, parentId);
        blockDetails.page_parent = blockDetails.page_parent;
    }else{
        // new parent block is not a direct child of page (root block)
        parentElement = this.findElement(this.page.elements, parentId);
        blockDetails.page_parent = 0;
    }

    blockDetails.parent_id = parentId;
    blockDetails.page_id = this.pageid;
    blockDetails.pageid = this.pageid;

    if(regenerateId === true){
        // get a new id because every block has a unique id
        AdminBlocks.log('AdminBlocks.addElementToPage - Generating new id for '+blockDetails.id);
        newid = 'jfxpage-'+this.pageid+'-'+blockDetails.module_key+'-'+this.numBlocks[blockDetails.module_key];
        while(document.getElementById(newid)){
            this.numBlocks[blockDetails.module_key]++;
            newid = 'jfxpage-'+this.pageid+'-'+blockDetails.module_key+'-'+this.numBlocks[blockDetails.module_key];
        };
        blockDetails.id = newid;
        if(document.getElementById(newid)){
            AdminBlocks.log('AdminBlocks.addElementToPage - Failed to find unique id for this block: '+newid+'!!!');
            alert('There is an error, we already have '+newid+', but this is what we found when trying to add element to page!!!');
            return;
        }

        AdminBlocks.log('found a unique id: '+newid+'!!!');
        blockDetails.id = 'page_'+this.pageid+'_module_'+blockDetails.module_key+'-'+this.numBlocks[blockDetails.module_key]+'-'+this.workspaceid;
        //$.post(AdminBlocks.ajaxUrl+'/copy-block-lang/', {origid : el.id, newid : blockDetails.id, details : JSON.stringify(blockDetails)});
    }

    // store our new block details
    i = parentElement.elements.length;
    parentElement.elements[i] = new Object;
    element = parentElement.elements[i];
    element.id = blockDetails.id;
    element.elements = Array();
    element.details = blockDetails;

    // create the new dom node representing our block on the canvas
    newEl = document.createElement('div');
    newEl.id = blockDetails.id;
    $(newEl).attr('class', blockDetails.class_name+' jfx-block');

    // create the content area where block content is displayed
    contentArea = document.createElement('div');
    contentArea.className = 'jfx-content-area';
    contentArea.innerHTML = blockDetails.default_content;

    // lets put our new dom node into the parent element
    $(newEl).append(contentArea);
    $('#'+parentId).append(newEl);

    // make it droppable if allowed
    if(blockDetails.is_droppable == 1) $(newEl).attr('class', $(newEl).attr('class')+' jfx-droppable');

    // create the block actions where users can manipulate the block
    this.createBlockActions(newEl, blockDetails);

    // apply real styles and content
    AdminBlocks.log('AdminBlocks.addElementToPage - Getting block content for '+el.id);
    $.getJSON(AdminBlocks.ajaxUrl+'/get-block-content/', {block : el.id, insertid : blockDetails.id}, AdminBlocks.insertBlockContent);

    AdminBlocks.log('AdminBlocks.addElementToPage - Getting block styles for '+el.id);
    $.getJSON(AdminBlocks.ajaxUrl+'/get-block-style/', {block : el.id, insertid : blockDetails.id}, AdminBlocks.updateBlockStyle);

    AdminBlocks.log('AdminBlocks.addElementToPage - Block has been created, now processing '+el.elements.length+' child elements...');

    // insert the child elements for this block
    for(i=0; i<el.elements.length; i++){
        AdminBlocks.addElementToPage(el.elements[i], blockDetails.id, regenerateId);
    }

    // save the details for insert menu
    this.setValue('blockMapper_'+blockDetails.id, blockDetails);


}




/**
 *  Called when a template or module block is inserted from the menu. This creates a new
 *  block on the page and saves it.
 */
JFX_AdminBlocks.prototype.addBlock = function(el, blockDetails){
alert(blockDetails.id);
    AdminBlocks.log('AdminBlocks.addBlock - new parent: '+el.id+', block title: '+blockDetails.title);

    var i, blockDetails2, parentElement, origBlockDetails;
    blockDetails2 = cloneObject(blockDetails);

    //var_dump(blockDetails2);

    // make sure each instance of this module block has a unique id
    if(typeof(blockDetails2.module_key)==='undefined'){
        AdminBlocks.log(blockDetails2.title+' is undefined!');
        return;
    }
    if(typeof(this.numBlocks[blockDetails2.module_key])==='undefined') this.numBlocks[blockDetails2.module_key] = 0;
    else this.numBlocks[blockDetails2.module_key]++;

    // find our parent element details, lets see if it is the page itself (root block)
    if(el.id === this.page.id){
        // yep, the page is the new parent block
        parentElement = this.page;
        blockDetails2.page_parent = 1;
    }else{
        // new parent block is not a direct child of page (root block)
        parentElement = this.findElement(this.page.elements, el.id);
        blockDetails2.page_parent = 0;
    }

    // get a new details object with the same values as the original block
    origBlockDetails = cloneObject(blockDetails);

    // update the settings that belong to the new block
    blockDetails2.parent_id = parentElement.id;
    blockDetails2.page_id = this.pageid;
    blockDetails2.workspace_id = this.workspaceid;

    //blockDetails.id = 'page_'+this.pageid+'_module_'+blockDetails.module_key+'-'+this.numBlocks[blockDetails.module_key]+'-'+this.workspaceid;

    // get a new id because every block has a unique id
    var newid = 'jfxpage-'+this.pageid+'-'+blockDetails2.module_key+'-'+this.numBlocks[blockDetails2.module_key];
    while(document.getElementById(newid)){
        this.numBlocks[blockDetails2.module_key]++;
        newid = 'jfxpage-'+this.pageid+'-'+blockDetails2.module_key+'-'+this.numBlocks[blockDetails2.module_key];
        //alert('trying for '+newid);
    }


    if(document.getElementById(newid)){
        AdminBlocks.log('Failed to find unique id for this block: '+newid+'!!!');
        alert('There is an error, we already have '+newid+', but this is what we found when trying to add block to page!!!');
        return;
    }
    blockDetails2.id = newid;
    AdminBlocks.log('found a unique id: '+newid+'!!!');

    // find out if this is a template or not
    if(AdminBlocks.templatePageId == origBlockDetails.page_id && AdminBlocks.mode == 'page'){
        // yes, let's create a mirror to the original block
        AdminBlocks.log('creating mirror of template block #'+origBlockDetails.id+' as new block: #'+newid);
        blockDetails2.template_id = origBlockDetails.id
    }else{
        // this block does not mirror a template block, let's instantiate some custom content for it
        AdminBlocks.log('Creating new instance of block (not template): #'+newid);
        blockDetails2.template_id = '';
        if(origBlockDetails.id != newid){
            $.post(AdminBlocks.ajaxUrl+'/copy-block-lang/', {origid : origBlockDetails.id, newid : newid, details : JSON.stringify(blockDetails2)});
        }
    }

    // toggled off for templates
    //if(AdminBlocks.mode == 'template') blockDetails2.is_droppable = 0;

    // store our new block details
    i = parentElement.elements.length;
    parentElement.elements[i] = new Object;
    var element = parentElement.elements[i];
    element.id = blockDetails2.id;
    element.pageid = blockDetails2.page_id;
    element.elements = Array();
    element.details = blockDetails2;
/*
    echo('<br />');
    var_dump(blockDetails);
    echo('<br />');
*/
    // create the new dom node representing our block on the canvas
    var newEl = document.createElement('div');
    newEl.id = blockDetails2.id;
    $(newEl).attr('class', blockDetails2.class_name+' jfx-droppable jfx-block');

    // create the content area where block content is displayed
    var contentArea = document.createElement('div');
    contentArea.className = 'jfx-content-area';
    contentArea.innerHTML = blockDetails2.default_content;
    $(newEl).append(contentArea);

    // lets put our new dom node into the parent element
    $(el).append(newEl);

    // create the block actions where users can manipulate the block
    this.createBlockActions(newEl, blockDetails2);

    // display the content
    $.getJSON(AdminBlocks.ajaxUrl+'/get-block-content/', {block : origBlockDetails.id, insertid: element.id}, AdminBlocks.insertBlockContent);

    AdminBlocks.log('Block has been created, now fetching details of child blocks to insert...');

    // insert the child elements for this block

    if(blockDetails.elements && blockDetails.elements.length > 0){
        alert('found '+blockDetails.elements.length+' child blocks, beginning to add now...');
        AdminBlocks.log('found '+blockDetails.elements.length+' child blocks, beginning to add now...');
        for(i=0; i < blockDetails.elements.length; i++){
            //AdminBlocks.addElementToPage(blockDetails2.elements[i], element.id, true);
            AdminBlocks.addBlock(newEl, blockDetails.elements[i]);
        }
    }else{
        alert('nochildblockstoinsert');
        AdminBlocks.log('Could not find any child elements for '+blockDetails.id);
    }

    // save the page
    AdminBlocks.log('Saving page');
    this.autoSavePage();

    AdminBlocks.log('Showing arrows to reposition blocks');
    // display the arrows enabling blocks to be moved up or down
    this.showArrows();
}









/**
 * Display the actions for each block, the buttons in .jfx-actions which can be clicked
 */
JFX_AdminBlocks.prototype.createBlockActions = function(el, details){

    if(!el){
        alert('Element missing!');
        return;
    }
    var actionsScreen = document.createElement('div');
    var actions = document.createElement('div');
    var isPage = (AdminBlocks.page.id == el.id);
    actions.className = 'jfx-actions';
    actions.id = 'jfx-actions_'+el.id;

    // the click button to show actions
    var btn = document.createElement('a');
    var btnImg = document.createElement('img');
    btnImg.src = ImageUrl+'/admin/layout/arrow-green-right.png';
    btnImg.alt = 'Options';
    $(btn).append(btnImg);
    btn.className = 'jfx-actions-button';
    btn.id = 'jfx-actions-button_'+el.id;
    $(btn).mouseenter(function(){
        AdminBlocks.showMyActions(btn.parentNode);
    });

    // heading - makes it J-editable
    var h3 = document.createElement('h3');
    h3.id = 'jeditableh3_'+el.id;
    h3.className = h3.id;
    $(h3).text(details.title);
    $(h3).click(function(){
        AdminBlocks.currentEditingH3 = this;
    });
    var editableFunction = function(value, settings){
        var h3 = AdminBlocks.currentEditingH3;
        var id = h3.id.replace('jeditableh3_', '');
        var arr = AdminBlocks.findElement(AdminBlocks.page.elements, id);
        arr.details.title = value;
        AdminBlocks.autoSavePage();
        return value;
    };
    var editableSettings = {
        'type' : 'text',
        'submit' : 'OK',
        'id' : this.id,
        'width' : '240'
    };
    $(h3).editable(editableFunction, editableSettings);

    $(actions).append(h3);

    // delete button
    var canDelete = true;

    if(isPage) canDelete = false;

    if(details.template_id && details.template_id.length > 0 && this.mode == 'page'){
        canDelete = false;
    }

    if(canDelete){
        var del = document.createElement('a');
        del.className = 'jfx-delete';
        del.href = 'javascript: void(null)';
        del.id = 'delete-'+el.id;
        $(del).click(function(){
            AdminBlocks.deleteBlock(this.id);
        });
        var delImage = document.createElement('img');
        delImage.src = ImageUrl+'/admin/icons/delete.gif';
        delImage.title = 'Delete Block';
        //$(del).text('Delete');
        $(del).append(delImage);
        actions.appendChild(del);
    }
/* removed 0.2.6
    // edit button
    var edit = document.createElement('a');
    edit.href = 'javascript: void(null)';
    edit.id = 'edit-'+el.id;
    edit.className = 'jfx-edit';
    $(edit).click(function(){
        AdminBlocks.editBlock(this.id);
    });
    var editImage = document.createElement('img');
    editImage.src = ImageUrl+'/admin/icons/edit.gif';
    editImage.title = 'Edit Content';
    //$(edit).text('Edit');
    $(edit).append(editImage);
    actions.appendChild(edit);

    // style
    var canStyle = true;

    if(isPage) canStyle = false;

    if(canStyle){
        var style = document.createElement('a');
        style.href = 'javascript: void(null)';
        style.id = 'style-'+el.id;
        $(style).click(function(){
            AdminBlocks.styleBlock(this.id);
        });
        var styleImage = document.createElement('img');
        styleImage.src = ImageUrl+'/admin/icons/style.gif';
        styleImage.title = 'Edit Styles';
        //$(style).text('Style');
        $(style).append(styleImage);
        actions.appendChild(style);
    }

    // save template button
    var save = document.createElement('a');
    save.href = 'javascript: void(null)';
    save.id = 'a-'+el.id;
    $(save).click(function(){
        AdminBlocks.saveTemplate(this.id);
    });
    var saveImage = document.createElement('img');
    saveImage.src = ImageUrl+'/admin/icons/save.gif';
    saveImage.title = 'Save as Template';
    //$(save).text('Save Template');
    $(save).append(saveImage);
    actions.appendChild(save);
*/

    // Insert block link - on hover, show the menu
    var canInsert = true;

    switch(AdminBlocks.mode){
        case 'template':
            if(isPage) canInsert = false;
        break;
        case 'page':
            if(isPage) canInsert = true;
        break;
    }

    // cannot delete blocks which are mirrors of templates when editing a page
    if(details.template_id && details.template_id.length > 0 && this.mode == 'page' && details.is_droppable == 0){
        canInsert = false;
    }

    if(canInsert){
        var insertMenu = document.createElement('a');
        insertMenu.className = 'jfx-insert-menu';
        insertMenu.id = 'jfx-insert-menu-'+el.id;
        $(insertMenu).html('Insert');
        $(insertMenu).hover(function(){
            AdminBlocks.addHoverInsertMenu(el, insertMenu);
        });
        $(actions).append(insertMenu);
    }

    //$('#jfx-header').append(actions);
    //$(el).append(actions);
    $('#jfx-actions-wrapper').css('display', 'none');

    $(actionsScreen).addClass('jfx-actions-screen');

    $(el).prepend(actionsScreen);
    $(el).prepend(actions);
    $(el).prepend(btn);

    $(actions).hover(function(){
        $(actionsScreen).css('display', 'block');
    }, function(){
        $(actionsScreen).css('display', 'none');
    });
}




/**
* Called by an event handler to make visible actions for selected block and hide all other actions
*/
JFX_AdminBlocks.prototype.showMyActions = function(el){
    var actionsEl = $('#jfx-actions_'+el.id).get(0);
    $(actionsEl).css('display', 'block');
    $('#jfx-actions-wrapper').css('display', 'block');
    if(AdminBlocks.visibleActions) $(AdminBlocks.visibleActions).css('display', 'none');
    AdminBlocks.visibleActions = actionsEl;
    AdminBlocks.log('showing actions for '+el.id);
}




/**
 * Calculates which blocks can be moved before or after it's siblings and shows arrows up/down
 */
JFX_AdminBlocks.prototype.showArrows = function(){
    $('.jfx-actions .jfx-arrow').each(function(){
        this.parentNode.removeChild(this);
    });

    var pageBlocks = $('.jfx-block').get();



    for(var i0 = 0; i0<pageBlocks.length; i0++){
        var el = pageBlocks[i0];


        if($('>.jfx-block', el.parentNode).get().length>1){
            var els = $('>.jfx-block', el.parentNode).get();
            var first = false;
            var last = false;
            for(var i=0; i<els.length; i++){
                if($('>.jfx-block', el.parentNode).get(i).id == el.id){
                    if(i==0) first = true;
                    else if(i == (els.length-1)) last = true;
                }
            }
            var details = AdminBlocks.findElement(AdminBlocks.page.elements, el.id);
            if(this.mode == 'page' && details.details.template_id.length > 0){
                continue;
            }
            if(!first){
                // show the up arrow
                var arrow = document.createElement('a');
                arrow.className = 'jfx-arrow';
                arrow.id = 'arrowup-'+el.id;
                var arrowImg = document.createElement('img');
                arrowImg.src = ImageUrl+'/admin/icons/up.png';
                arrowImg.alt = 'Up';
                arrowImg.title = 'Move Up';
                $(arrow).append(arrowImg);
                $(arrow).click(function(){
                    var id = this.id;
                    id = id.split('-');
                    id = id.splice(1);
                    id = id.join('-');
                    AdminBlocks.moveUp(id);
                });
                $('#jfx-actions_'+el.id).get(0).appendChild(arrow);
            }
            if(!last){
                // show the down arrow
                var arrow = document.createElement('a');
                arrow.className = 'jfx-arrow';
                arrow.id = 'arrowdown-'+el.id;
                var arrowImg = document.createElement('img');
                arrowImg.src = ImageUrl+'/admin/icons/down.png';
                arrowImg.alt = 'Down';
                arrowImg.title = 'Move Down';
                $(arrow).append(arrowImg);
                $(arrow).click(function(){
                    var id = this.id;
                    id = id.split('-');
                    id = id.splice(1);
                    id = id.join('-');
                    AdminBlocks.moveDown(id);
                });
                $($('#jfx-actions_'+el.id).get(0)).append(arrow);
            }else{
                // no arrows shown, it is the only element
            }
        }

    }

}

/**
 * Moves the block before previous sibling
 */
JFX_AdminBlocks.prototype.moveUp = function(id){
    var el = $('#'+id).get(0);
    var parent = this.findParent(this.page, el.id);
    var key = this.findKey(parent, el.id);
    if(key == 0) return;
    var newKey = key-1;
    var tmpEl = parent.elements[key];
    parent.elements[key] = parent.elements[newKey];
    parent.elements[newKey] = tmpEl;
    var els = $(el.parentNode).children('.jfx-block');
    $(els[newKey]).before(el);
    AdminBlocks.autoSavePage();
    AdminBlocks.showArrows();
}
/**
 * Moves the block after following sibling
 */
JFX_AdminBlocks.prototype.moveDown = function(id){
    var el = $('#'+id).get(0);
    var parent = this.findParent(this.page, el.id);
    var key = this.findKey(parent, el.id);
    if(key == (parent.elements.length-2)) return;
    var newKey = key+1;
    var tmpEl = parent.elements[key];
    parent.elements[key] = parent.elements[newKey];
    parent.elements[newKey] = tmpEl;
    var els = $(el.parentNode).children('.jfx-block');
    $(els[newKey]).after(el);
    AdminBlocks.autoSavePage();
    AdminBlocks.showArrows();
}





/**
 * display thickbox to edit block content
 */
JFX_AdminBlocks.prototype.editBlock = function(id){
    id = id.split('-');
    id.splice(0, 1);
    id = id.join('-');
    var parent = document.getElementById(id).parentNode;
    var href = AjaxUrl+'/edit-block-instance/?id='+id+'&parent='+parent.id+'&KeepThis=true&TB_iframe=true&height=500&width=700';
    tb_show('Editing Block Details', href, false);
    AdminBlocks.editingBlockId = id;
    $("#TB_window").unload(function () {
        $.getJSON(AdminBlocks.ajaxUrl+'/get-block-content/', {block : AdminBlocks.editingBlockId}, AdminBlocks.insertBlockContent);
    });
}
/**
 * Apply block content
 */
JFX_AdminBlocks.prototype.insertBlockContent = function(content){
    $('#'+content.id+' .jfx-content-area').get(0).innerHTML = content.content;
    //alert('inserted '+content.id+' '+content.content);
    $('#'+content.id+' .jfx-content-area form').get(function(){
        this.action = 'javascript: void(null)';
    });
}

/**
 * display thickbox to edit block style
 */
JFX_AdminBlocks.prototype.styleBlock = function(id){
    id = id.split('-');
    id.splice(0, 1);
    id = id.join('-');
    var parent = document.getElementById(id).parentNode;
    var href = AjaxUrl+'/style-block/?id='+id+'&parent='+parent.id+'&KeepThis=true&TB_iframe=true&height=500&width=700';
    tb_show('Styling Block', href, false);
    AdminBlocks.editingBlockId = id;
    $("#TB_window").unload(function () {
        $.getJSON(AdminBlocks.ajaxUrl+'/get-block-style/', {block : AdminBlocks.editingBlockId}, AdminBlocks.updateBlockStyle);
    });
}
/**
 * Apply block style
 */
JFX_AdminBlocks.prototype.updateBlockStyle = function(style){
    var el = $('#'+style.id).get(0);
    $(el).attr('style', style.block_style);
    if(style.is_droppable==1) style.class_name += ' jfx-droppable';
    style.class_name += ' jfx-block';
    el.className = style.class_name;
}










/**
 * Automatically save the page.
 */
JFX_AdminBlocks.prototype.autoSavePage = function(){
    var useResponseFunction = true;
    var responseFunction = this.confirmSavePage;
    this.savePage(useResponseFunction, responseFunction);
}
/**
 * Save the page, manually supply response function
 */
JFX_AdminBlocks.prototype.savePage = function(useResponseFunction, responseFunction){
    if(useResponseFunction!==true){
        this.callSaveResponseFunction = false;
        this.saveResponseFunction = responseFunction;
    }else{
        this.callSaveResponseFunction = true;
        this.saveResponseFunction = responseFunction;
    }


    var json = JSON.stringify(this.page);
    //var json = this.page.serialize();
    var data = {
        'type' : 'post',
        'datatype' : 'json',
        'data' : json
    }
    //$.getJSON(AjaxUrl+'/save-page', data, this.confirmSave);
    $.post(AjaxUrl+'/save-page/', data, this.confirmSave);
    //alert(json);
}
/**
 * Display confirmation or failure after page save
 */
JFX_AdminBlocks.prototype.confirmSavePage = function(success, message){
    if(success){
        alert('Save successful!');
        //window.location = this.saveLocation;
    }else{
        alert('Error saving: '+message);
    }
}

/**
 * Save the block as a template (deprecated)
 */
JFX_AdminBlocks.prototype.saveTemplate = function(id){
    alert('JFX_AdminBlocks.saveTemplate is deprecated, please use Website Content > Templates');
    id = id.split('-');
    id.splice(0, 1);
    id = id.join('-');
    var url = AjaxUrl+'/save-block-template/';
    var el = this.findElement(this.page.elements, id);

    $.post(url, {id : id, title: el.details.title, element: JSON.stringify(el)}, AdminBlocks.confirmSaveBlockTemplate);
}
/**
 * Display confirmation or failure after template save (deprecated)
 */
JFX_AdminBlocks.prototype.confirmSaveBlockTemplate = function(json){
    json = JSON.parse(json);
    alert('JFX_AdminBlocks.saveTemplate is deprecated, please use Website Content > Templates');
    if(json.status == 'OK') alert('Save success!');
}



























/**
 * Hide the insert menu
 */
JFX_AdminBlocks.prototype.hideInsertMenu = function(el, link){
    // hide the menu
    if(!el) el = AdminBlocks.elementForInserting;
    if(!el) return;
    if(!link) link = el;
    var left = AdminBlocks.getX(link);
    if((left + $('#jfx-insert-menu').get(0).clientWidth) > document.clientWidth){
        left = document.clientWidth - $('#jfx-insert-menu').get(0).clientWidth;
    }
    left = -1864;
    AdminBlocks.log('Hide insert menu for '+el.id+' with left of '+left+'px');
    $('#jfx-insert-menu').animate({opacity : 0, display : 'none', left : left}, 1200);
    AdminBlocks.elementForInserting = null;
    return;
}

/**
 * Display the insert menu, provide the target block element to insert to, and the trigger-button element for alignment
 */
JFX_AdminBlocks.prototype.addHoverInsertMenu = function(el, link){
    var top = AdminBlocks.getY(link)+link.offsetHeight;
    var left = AdminBlocks.getX(link);

    if(AdminBlocks.elementForInserting && AdminBlocks.elementForInserting.id == el.id){
        return;
    }

    AdminBlocks.log('Show insert menu for '+el.id);
    AdminBlocks.elementForInserting = el;

    $('#jfx-insert-menu').css('top', top);
    $('#jfx-insert-menu').css('left', left);
    $('#jfx-insert-menu').css('display', 'block');
    if((left) > document.body.clientWidth-640){
        var newLeft = document.body.clientWidth-640;
    }else{
        newLeft = left;
    }

    $('#jfx-insert-menu').css('opacity', 0);
    $('#jfx-insert-menu').css('left', newLeft+'px');
    $('#jfx-insert-menu').animate({opacity : 1}, 1200);

    $('a.jfx-insert-menu').mouseenter(function(){
        $('#jfx-insert-menu').trigger('mouseenter');
    });
}

JFX_AdminBlocks.prototype.toggleFullScreen = function(){
    if(this.fullScreen === true){
        $('.jfxt-banner, .jfxt-footer-full').slideDown('slow');
        $('.jfxt-black-menu').css('z-index', 0);
        this.fullScreen = false;
    }else{
        $('.jfxt-banner, .jfxt-footer-full').slideUp('slow');
        $('.jfxt-black-menu').css('z-index', 2);
        this.fullScreen = true;
    }
}


/**
 * Toggle the view mode to full-screen or normal
 *
JFX_AdminBlocks.prototype.toggleFullScreen = function(){
    var pageEl, newParent, menuEl;
    menuEl = $('.jfxt-black-menu').get(0);
    pageEl = $('#jfx-page-workspace').get(0);
    if(this.fullScreen){
        // restore to normal
        $(menuEl).css({
            'position' : 'relative',
            'top' : '0'
        });
        $(pageEl).css({
            'position' : 'relative',
            'top' : '0'
        });
        $('.jfxt-banner, .jfxt-footer-full').css({
            'display' : 'block'
        });
        clearTimeout(this.hideFullScreenTabTimeout);
        
        newParent = $('#jfx-workspace-wrapper').get(0);
        $(pageEl).prependTo(newParent);
       
        this.fullScreen = false;
    }else{
        // display full-screen
        newParent = $('body').get(0);
        $(pageEl).prependTo(newParent);
        $(menuEl).css({
            'position' : 'absolute',
            'left' : '0',
            'top' : '0',
            'width' : '100%',
            'z-index' : 2
        });
        $(pageEl).css({
            'top' : (menuEl.clientHeight+16)+'px',
            'position' : 'absolute',
            'z-index' : '2'
        });
        $('.jfxt-banner, .jfxt-footer-full').css({
            'display' : 'none'
        });
        this.fullScreen = true;
    }
}

















/**
 * Obtain the details of the parent element
 * var parentEl = this.findParent(this.page, myEl.id);
 */
JFX_AdminBlocks.prototype.findParent = function(el, id){
    if(el.elements.length == 0) return false;
    var parentNode = el;
    for(var i=0; i<el.elements.length; i++){
        if(el.elements[i].id == id){
            return parentNode;
        }
        else if(el.elements[i].elements.length > 0){
            var found = this.findParent(el.elements[i], id);
            if(typeof(found) == 'object'){
                return found;
            }
        }
    }
    return false;
}

/**
 * Find the data key in a set of elements where an id is known
 *
 */
JFX_AdminBlocks.prototype.findKey = function(el, id){
    if(el.elements.length == 0) return false;
    for(var i=0; i<el.elements.length; i++){
        if(el.elements[i].id == id) return i;
    }
    return false
}

/**
 * Find an element in this.page, which contains all json data about page elements.
 * Returns array of data from JFX_Block::getDetails()
 */
JFX_AdminBlocks.prototype.findElement = function(elements, id){
    if(id == 'jfxpage-'+AdminBlocks.pageid){
        return AdminBlocks.page;
    }
    for(var i=0; i<elements.length; i++){
        if(elements[i].id == id){
            return elements[i];
        }
        else if(elements[i].elements.length > 0){
            var found = this.findElement(elements[i].elements, id);
            if(found !== false){
                return found;
            }
        }
    }
    return false;
}







